<!-- 节假日 -->
<template>
  <div class="calendar-box">
    <div class="calendar-main">
      <div style="min-height:32px;line-height: 32px;">
        <span class="name">节假日设置</span>
        <span class="tags">
          <span v-show="tags.length>0">更改月份:</span>
          <el-tag
            v-for="tag in tags"
            :key="tag"
            closable
            type="warning"
            @close="tagClose(tag)"
            @click="tagClick(tag)">
            {{tag}}
          </el-tag>
        </span>
      </div>
      <div class="title-box">
        <div class="left-box">
          <el-button icon="el-icon-arrow-left" @click="prevent"></el-button>
          <el-date-picker
            v-model="month"
            type="month"
            placeholder="选择月"
            :clearable="false"
          >
          </el-date-picker>
          <el-button icon="el-icon-arrow-right" @click="next"></el-button>
        </div>
        <div class="right-box">
          <span class="span-click" @click="downLoadExcel">Excel模板下载</span>
          <el-upload
            action=""
            :auto-upload="false"
            accept=".xlsx, .xls"
            :show-file-list="false"
            :on-change="importExcel"
          >
            <el-button>Excel导入</el-button>
          </el-upload>
          <el-dropdown @command="chooseType">
            <el-button type="primary">
              批量设置休息日<i class="el-icon-arrow-down el-icon--right"></i>
            </el-button>
            <el-dropdown-menu slot="dropdown">
              <el-dropdown-item command="sunday">所有周日</el-dropdown-item>
              <el-dropdown-item command="saturday">所有周六</el-dropdown-item>
              <el-dropdown-item command="all">所有周末</el-dropdown-item>
              <el-dropdown-item command="cancle">取消批量设置</el-dropdown-item>
            </el-dropdown-menu>
          </el-dropdown>
        </div>
      </div>
      <el-calendar v-model="selectedDay" v-loading="loading">
        <template
          slot="dateCell"
          slot-scope="{date, data}"
        >
          <div class="calendarBox" @click="calendarClick(data.day,date)">
            {{date.getDate()}}
            <div v-if="isHolidayOriginal(date,data)" class="circle red">
              <div class="holiday">休</div>
            </div>
            <div v-else-if="isHolidayNew(date,data)" class="circle green">
              <div class="holiday">休</div>
            </div>
          </div>
        </template>
      </el-calendar>
    </div>
    <div class="buttons">
      <el-button type="primary" class="save-button" @click="save">提交</el-button>
      <el-button class="save-button" @click="cancle">重置</el-button>
      <el-button class="save-button" @click="cancleAll">全部撤销</el-button>
    </div>
  </div>
</template>

<script>
import { getHolidayList, setHolidayList } from '@/api/api.js'
import dateTime from '@/utils/dateTime.js'
import xlsx from 'xlsx'
export default {
  name: '',
  mixins: [],
  components: {},
  props: {
    hospitalCode: {
      String,
      default: ''
    }
  },
  data() {
    return {
      selectedDay: null,
      year: '',
      month: new Date(),
      dayType: '',
      originalObj: {},
      dataObj: {},
      loading: false,
      tags: []
    }
  },
  watch: {
    selectedDay(val) {
      this.dayType = 'cancle'
      if (val.getMonth() === 11 && this.month.getMonth() === 0) {
        this.prevent()
      } else if (val.getMonth() === 0 && this.month.getMonth() === 11) {
        this.next()
      } else if (val.getMonth() > this.month.getMonth()) {
        this.next()
      } else if (val.getMonth() < this.month.getMonth()) {
        this.prevent()
      }
    },
    hospitalCode() {
      this.dataObj = {}
      this.originalObj = {}
      this.getAndDealData()
    },
    month(val, oldVal) {
      this.dayType = 'cancle'
      // 在切换月份之前回填更改后的数据到dataObj
      let oldmval = this.dealMonth(oldVal)
      this.dataObj[oldmval] = Array.from(this.holidayArr)
      // 获取数据，显示数据
      //   let mval = this.dealMonth(val)
      this.getAndDealData()
    //   this.getData()
    //   if (!this.dataObj[mval]) {
    //     this.getData()
    //   } else {
    //     this.holidayArr = new Set(this.dataObj[mval])
    //     this.reRender()
    //   }
    }
  },
  computed: {},
  created() {
    this.holidayArr = new Set()
    this.getAndDealData()
  },
  mounted() {
  },
  methods: {
    downLoadExcel() {
      /* require.ensure([], () => {
        const { export_json_to_excel } = require('@/vendor/Export2Excel')// 引入文件
        const tHeader = ['日期', '节假日'] // 将对应的属性名转换成中文
        const data = []
        export_json_to_excel({ header: tHeader, data: data, filename: '节假日模板', autoWidth: false, width: '20' })
      }) */
      var a = document.createElement('a')
      a.download = '节假日模板.xlsx'
      a.href = '/static/file/节假日模板.xlsx'
      let body = document.getElementsByTagName('body')[0]
      body.appendChild(a) // 修复firefox中无法触发click
      a.click()
      body.removeChild(a)
    },
    async importExcel(ev) {
      let file = ev.raw
      if (!file) return
      let reader = await this.upload(file)

      const worker = xlsx.read(reader, { type: 'binary' })
      // 这个是将数据进行一步拼接
      //  worker.Sheets[worker.SheetNames[0]]

      // 将返回的数据转换为json对象的数据
      reader = xlsx.utils.sheet_to_json(worker.Sheets[worker.SheetNames[0]])
      try {
        let isNowMonth = false
        for (const v of reader) {
          let nDate = new Date(v['日期'])
          let year = nDate.getFullYear()
          let month = nDate.getMonth() + 1 > 9 ? nDate.getMonth() + 1 : '0' + (nDate.getMonth() + 1)
          let holidayMonth = `${year}-${month}`
          if (holidayMonth === this.dealMonth(this.month)) {
            isNowMonth = true
          }
          if (!this.dataObj[holidayMonth]) {
            let list = await this.getData(holidayMonth)
            this.dataObj[holidayMonth] = list.map(m => {
              return m.holiday.replace(' 00:00:00', '')
            })
            this.originalObj[holidayMonth] = list.map(m => {
              return m.holiday.replace(' 00:00:00', '')
            })
          }
          if (this.dataObj[holidayMonth].indexOf(dateTime.formartDate(nDate)) == -1) {
            this.dataObj[holidayMonth].push(dateTime.formartDate(nDate))
          }
        }
        // 重新刷日历页面
        if (isNowMonth) {
          this.holidayArr = new Set(this.dataObj[this.dealMonth(this.month)])
          this.month.setHours(8)
          this.reRender()
        }
        this.getTags()
        this.$message.success('节假日导入成功')
      } catch (error) {
        console.warn(error)
        this.$message({
          type: 'warning',
          message: '解析文件失败，请检查导入数据'
        })
      }

      // 将读取出来的数据转换为可以发送给服务器的数据
    //   let arr = []
    //   reader.forEach(item => {
    //     let obj = {}
    //     let character = {
    //       date: {
    //         text: '日期',
    //         type: String
    //       },
    //       name: {
    //         text: '节假日',
    //         type: String
    //       }
    //     }
    //     for (let key in character) {
    //       if (!character.hasOwnProperty(key)) break
    //       let v = character[key]
    //       let text = v.text
    //       let type = v.type
    //       v = item[text] || ''
    //       type === 'string' ? (v = String(v)) : null
    //       type === 'number' ? (v = String(v)) : null
    //       obj[key] = v
    //     }
    //     arr.push(obj)
    //   })
    //   console.log(arr)
    },
    upload(file) {
      return new Promise(resolve => {
        let reader = new FileReader()
        reader.readAsBinaryString(file)
        reader.onload = ev => {
          resolve(ev.target.result)
        }
      })
    },
    async save() {
      let changeData = this.getChangeMonth()
      let errs = []
      let success = []
      let cdArr = Object.keys(changeData)
      if (cdArr.length === 0) {
        this.$message.warning('请修改节假日数据')
        return
      }
      for (let k in changeData) {
        let params = {
          hospitalCode: this.hospitalCode,
          month: k,
          holidays: changeData[k]
        }
        await this.saveData(params).then(rs => {
          success.push(rs)
        }).catch((err) => {
          errs.push(err)
        })
      }
      if (success.length === cdArr.length) {
        this.$message({
          type: 'success',
          message: '成功设置' + success.join('、') + '月数据'
        })
      } else if (errs.length === cdArr.length) {
        this.$message({
          type: 'error',
          message: '未成功设置' + errs.join('、') + '月数据'
        })
      } else {
        this.$message({
          type: 'warning',
          message: '成功设置' + success.join('、') + '月,未成功设置' + errs.join('、') + '月数据'
        })
      }
      success.forEach(v => {
        this.originalObj[v] = this.dataObj[v]
      })
      this.getTags()
      this.reRender()
    },
    saveData(params) {
      return new Promise((rs, rj) => setHolidayList(params).then(res => {
        if (res.code === 10000) {
          rs(params.month)
          this.originalObj[params.month] = JSON.parse(JSON.stringify(params.holidays))// 保存完以后赋值给源数据，做撤销用
          this.dataObj[params.month] = JSON.parse(JSON.stringify(params.holidays))
        } else {
          rj(params.month)
        }
      }))
    },
    cancle() {
      // 这是撤销当前修改月的
      if (this.tags.indexOf(this.dealMonth(this.month)) > -1) {
        this.month.setHours(12)
        this.holidayArr = new Set(this.originalObj[this.dealMonth(this.month)])
        this.reRender()
        this.tags.splice(this.tags.indexOf(this.dealMonth(this.month)), 1)
      }
    },
    cancleAll() {
      // 这是撤销所有修改月份的
      this.month.setHours(12)
      this.holidayArr = new Set(this.originalObj[this.dealMonth(this.month)])
      this.reRender()
      this.dataObj = JSON.parse(JSON.stringify(this.originalObj))
      this.tags = []
    },
    reRender() {
      /* 通知页面重新渲染 */
      this.selectedDay = new Date(this.month)
    },
    isHolidayOriginal(date, data) {
      // 判断值是否是节假日，并且是已经保存的数据
      if (data.type === 'current-month' && (this.dayType.indexOf(date.getDay()) > -1 || Array.from(this.holidayArr).indexOf(data.day) > -1)) {
        this.holidayArr.add(data.day)
        let month = this.dealMonth(date)
        let original = this.originalObj[month]
        if (original && original.indexOf(data.day) > -1) {
          return true
        } else {
          return false
        }
      } else {
        return false
      }
    },
    isHolidayNew(date, data) {
      // 判断值是否是节假日，并且是新添加的数据
      if (data.type === 'current-month' && (this.dayType.indexOf(date.getDay()) > -1 || Array.from(this.holidayArr).indexOf(data.day) > -1)) {
        return true
      } else {
        return false
      }
    },
    chooseType(val) {
      if (val === 'sunday') {
        this.dayType = '0'
        for (let item of this.holidayArr) {
          let currentMonth = this.selectedDay.getMonth() + 1 > 9 ? this.selectedDay.getMonth() + 1 : '0' + (this.selectedDay.getMonth() + 1)
          if (item.split('-')[1].indexOf(currentMonth) > -1 && new Date(item).getDay() === 6) { // 当前月的数据
            this.holidayArr.delete(item)
          }
        }
      }
      if (val === 'saturday') {
        this.dayType = '6'
        for (let item of this.holidayArr) {
          let currentMonth = this.selectedDay.getMonth() + 1 > 9 ? this.selectedDay.getMonth() + 1 : '0' + (this.selectedDay.getMonth() + 1)
          if (item.split('-')[1].indexOf(currentMonth) > -1 && new Date(item).getDay() === 0) { // 当前月的数据
            this.holidayArr.delete(item)
          }
        }
      }
      if (val === 'all') {
        this.dayType = '0,6'
      }
      if (val === 'cancle') {
        this.dayType = ''
        for (let item of this.holidayArr) {
          let currentMonth = this.selectedDay.getMonth() + 1 > 9 ? this.selectedDay.getMonth() + 1 : '0' + (this.selectedDay.getMonth() + 1)
          if (item.split('-')[1].indexOf(currentMonth) > -1 && (new Date(item).getDay() === 0 || new Date(item).getDay() === 6)) { // 当前月的数据
            this.holidayArr.delete(item)
          }
        }
      }
      this.$nextTick(() => {
        this.getTags()
      })
    },
    prevent() {
      /* 上一个月 */
      this.month = new Date(this.month.getFullYear(), this.month.getMonth() - 1, '01')
    },
    next() {
      /* 下一个月 */
      this.month = new Date(this.month.getFullYear(), this.month.getMonth() + 1, '01')
    },
    dealMonth(val) {
      let monthDay = val.getFullYear() + '-'
      let fullMonth = val.getMonth() + 1 > 9 ? val.getMonth() + 1 : '0' + (val.getMonth() + 1)
      return monthDay + fullMonth
    },
    getData(month) {
      return new Promise((rs, rj) => {
        this.loading = true
        getHolidayList({ hospitalCode: this.hospitalCode, Month: month }).then((res) => {
          this.loading = false
          if (res.code === 10000) {
            rs(res.content.list)
          }
        }).catch(() => {
          rj()
          this.loading = false
        })
      })
    },
    dealData(list, month) { // 处理从后台获到的数据
      let data = []
      list.forEach(el => {
        let day = el.holiday.replace(' 00:00:00', '')
        data.push(day)
      })
      this.holidayArr = new Set(data)
      this.originalObj[month] = JSON.parse(JSON.stringify(data))
      if (!this.dataObj[month]) {
        this.dataObj[month] = data
      } else {
        data.forEach(v => {
          if (this.dataObj[month].indexOf(v) == -1) {
            this.dataObj[month].push(v)
          }
        })
        this.holidayArr = new Set(this.dataObj[month])
      }
      this.selectedDay = this.month// 拿到数据以后设置一下日期，改变数据通知页面渲染
    },
    getAndDealData() {
      let month = this.dealMonth(this.month)
      this.getData(month).then(list => {
        this.dealData(list, month)
      })
    },
    calendarClick(day, date) {
      if (date.getMonth() === this.month.getMonth()) {
        if (Array.from(this.holidayArr).indexOf(day) > -1) {
          // 如果已存在该值就为取消这一天
          this.holidayArr.delete(day)
        } else {
          // 如果不存在该值就是新增这一天
          this.holidayArr.add(day)
        }
        this.getTags()
      }
    },
    getTags() {
      let changeMonth = this.getChangeMonth()
      this.tags = Object.keys(changeMonth)
    },
    getChangeMonth() {
      // 把当前月的数据存到dataObj里
      this.dataObj[this.dealMonth(this.month)] = Array.from(this.holidayArr)
      // 对比找出更改过的月，提交给后台
      let changeData = {}
      for (let key in this.dataObj) {
        let data = this.dataObj[key] || []
        let original = this.originalObj[key] || []
        if (data.length !== original.length) {
          changeData[key] = data
        } else {
          data.sort()
          original.sort()
          let flag = false
          data.forEach((e, index) => {
            if (data[index] !== original[index]) {
              flag = true
            }
          })
          if (flag) {
            changeData[key] = data
          }
        }
      }
      return changeData
    },
    tagClose(month) {
      this.dataObj[month] = JSON.parse(JSON.stringify(this.originalObj[month]))
      if (month === this.dealMonth(this.month)) {
        this.cancle()
      } else {
        this.tags.splice(this.tags.indexOf(month), 1)
      }
    },
    tagClick(month) {
      this.month = new Date(month + '-01')
    }
  },
  beforeDestroy() {},
  destroyed() {},
  beforeUpdate() {},
  updated() {}
}
</script>
<style lang='scss' scoped>
.calendar-box{
    width:100%;
    height:100%;
    .buttons{
            width: 100%;
            height: 48px;
            background: #FFFFFF;
            border: 1px solid #E8E8E8;
            position: fixed;
            right: 0;
            bottom: 0;
            padding: 7px 0;
            .el-button{
                font-size:14px;
            }
            .save-button{
                float: right;
                margin-right: 10px;
                height: 32px;
                line-height: 7px;
            }
        }
    .calendar-main{
        width:100%;
        height:calc(100% - 48px);
        padding:24px;
        font-size:12px;
        .name{
            font-family: PingFangSC-Medium, PingFang SC;
            font-weight: 600;
            font-size:14px;
        }
        .title-box{
            display:flex;
            justify-content: space-between;
            margin: 16px 0px 12px;
            .right-box{
                display: flex;
                align-items: center;
                width: 310px;
                justify-content: space-between;
                .span-click{
                    color:rgb(0, 204, 255);
                    cursor: pointer;
                }
            }
        }
        .el-calendar{
            /deep/ .el-scrollbar__wrap{
                width:100%;
            }
            /deep/ .el-calendar__header{
                display: none;
            }
            /deep/ .el-calendar__body{
                padding:0px;
            }
            /deep/ .el-calendar-table{
                thead{
                    th{
                        padding: 5px 0;
                        background: #F1F2F6;
                        border: 1px solid #E9E9E9;
                        font-size: 13px;
                    }
                    th::before{
                        content:'星期'
                    }
                }
                .el-calendar-table__row{
                    .el-calendar-day{
                        height: 120px;
                        font-size:18px;
                        padding:0px
                    }
                }
            }
        }
        .calendarBox{
            width:100%;
            height:100%;
            padding:8px;
            .circle{
                width: 62px;
                height: 62px;
                border-radius: 32px;
                // background: #eb4f4f6b;
                margin: auto;
                .holiday{
                    font-size: 16px;
                    font-family: PingFangSC-Medium, PingFang SC;
                    font-weight: 500;
                    line-height: 62px;
                    text-align: center;
                }
            }
            .red{
                background: #eb4f4f6b;
                .holiday{
                    color: #EB4F4F;
                }
            }
            .green{
                background: #3ea95e6b;
                .holiday{
                    color: #246946;
                }
            }
        }
    }
    .tags{
        max-width:80%;
        margin: 3px 0 3px 20px;
        .el-tag{
            margin:0 5px;
        }
    }
}
.el-button--primary{
    background: #00C0EF;
}
.el-input /deep/ .el-input__inner{
    height: 32px;
    line-height: 0;
    /deep/ .el-input__icon{
       line-height: 32px;
    }
}
.el-select{
    width:96px;
}
.el-date-editor{
    width:160px;
    font-size:12px;
}
.el-select /deep/ .el-input__inner{
    height: 32px;
    line-height: 0;
    font-size:12px;
}
.el-input /deep/ .el-input__icon{
       line-height: 32px;
}
.el-select /deep/ .el-input__icon{
       line-height: 32px;
}
.el-button{
    height: 32px;
    line-height: 0;
    padding: 5px 12px;
    font-size:12px;
}
.el-scrollbar /deep/ .el-scrollbar__wrap{
  overflow: auto;
  overflow-x: hidden;
}
.el-tag{
    cursor: pointer;
}
</style>
